package com.xiaoer.xiaoerdemo

import android.content.Context
import android.graphics.Color
import android.media.AudioManager
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.Adapter
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONObject
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.PlaybackException
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.ui.StyledPlayerView
import com.xiaoer.core.net.RetrofitUtils
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import java.io.BufferedReader
import java.io.InputStreamReader
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.TimeZone


class MainActivity : AppCompatActivity() {

    private lateinit var ll_channel_list: LinearLayout
    private lateinit var rv_channel: RecyclerView
    private lateinit var tv_channel_name: TextView
    private lateinit var tv_channel_playing_info: TextView
    private lateinit var tv_channel_program_next: TextView
    private lateinit var tv_all_tv_program: TextView
    private lateinit var rvAdapter: RvAdapter
    private lateinit var v_click: View
    val channelBean: MutableList<ChannelBean> = mutableListOf()
    var currentPlayingChannel: ChannelBean? = null
    private lateinit var styled_player_view: StyledPlayerView
    private lateinit var player: ExoPlayer
    private lateinit var progress_indicator: ProgressBar

    val countDownTimerOfPlayReady = object : CountDownTimer(8000, 1000) {
        override fun onTick(millisUntilFinished: Long) {
            Log.e(
                "@@@",
                "millisUntilFinished->" + player.playbackState + " --- " + player.isPlaying
            )
        }

        override fun onFinish() {
            Log.e("@@@", "倒计时结束" + player.playbackState + " --- " + player.isPlaying)
            if (player.isPlaying) {
                return
            }
            rvAdapter.changeNextChannelSource()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        ll_channel_list = findViewById(R.id.ll_channel_list)
        rv_channel = findViewById(R.id.rv_channel)
        tv_channel_name = findViewById(R.id.tv_channel_name)
        tv_channel_playing_info = findViewById(R.id.tv_channel_playing_info)
        tv_channel_program_next = findViewById(R.id.tv_channel_program_next)
        tv_all_tv_program = findViewById(R.id.tv_all_tv_program)
        progress_indicator = findViewById(R.id.progress_indicator)
        v_click = findViewById(R.id.v_click)
        styled_player_view = findViewById(R.id.styled_player_view)
        player = ExoPlayer.Builder(this).build()
        //设置player不休眠

        player.addListener(object : Player.Listener {
            override fun onPlaybackStateChanged(playbackState: Int) {
                super.onPlaybackStateChanged(playbackState)
                Log.e("***", "onPlaybackStateChanged->" + playbackState);
                when (playbackState) {
                    Player.STATE_ENDED -> {
                        //播放结束
                        player.stop()
                    }

                    Player.STATE_BUFFERING -> {
                        //缓冲中
                        progress_indicator.visibility = View.VISIBLE
//                        countDownTimerOfPlayReady.start()
                    }

                    Player.STATE_IDLE -> {
                        //空闲
                    }

                    Player.STATE_READY -> {
                        //准备好
                        progress_indicator.visibility = View.GONE
                        countDownTimerOfPlayReady.cancel()
                    }
                }
            }

            override fun onPlayerError(error: PlaybackException) {
                super.onPlayerError(error)
                rvAdapter.changeNextChannelSource()
                Log.e("***", "onPlayerError->" + error.message);
            }

            override fun onIsPlayingChanged(isPlaying: Boolean) {
                super.onIsPlayingChanged(isPlaying)
                Log.e("***", "onIsPlayingChanged->" + isPlaying);
            }
        })
        readChannelRaw()

        rvAdapter = RvAdapter()
        rv_channel.layoutManager = LinearLayoutManager(this)
        rv_channel.adapter = rvAdapter

        if (rvAdapter.itemCount != 0) {
            var lastPlayPosition = getLastPlayPosition()
            rvAdapter.setCurrentChannel(if (lastPlayPosition >= rvAdapter.itemCount) 0 else lastPlayPosition)
        }

        v_click.setOnClickListener {
            if (ll_channel_list.visibility == View.VISIBLE) {
                rvAdapter.showChannelInfo(false, true)
            } else {
                rvAdapter.showChannelInfo(true, true)
            }
        }
    }

    override fun onResume() {
        super.onResume()
        if (player != null) {
            player.play()
        }
    }

    override fun onPause() {
        super.onPause()
        if (player != null) {
            player.pause()
        }
    }

//    override fun onStop() {
//        super.onStop()
//        if (player != null) {
//            player.stop()
//        }
//    }

    private fun readChannelRaw() {
        val openRawResource = resources.openRawResource(R.raw.channels)
        var bufferedReader = BufferedReader(InputStreamReader(openRawResource))
        val json: StringBuilder = StringBuilder()
        bufferedReader.lineSequence().forEach {
            json.append(it)
        }
        var parseArray = JSONObject.parseArray(json.toString(), ChannelBean::class.java)
        channelBean.addAll(parseArray)
    }

    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
        if (event.action == KeyEvent.ACTION_UP) {
            when (event.keyCode) {
                KeyEvent.KEYCODE_DPAD_DOWN -> {
                    if (rvAdapter.currentId + 1 >= channelBean.size) {
                        rvAdapter.setCurrentChannel(0)
                    } else {
                        rvAdapter.setCurrentChannel(rvAdapter.currentId + 1)
                    }
                }

                KeyEvent.KEYCODE_DPAD_UP -> {
                    if (rvAdapter.currentId - 1 < 0) {
                        rvAdapter.setCurrentChannel(channelBean.size - 1)
                    } else {
                        rvAdapter.setCurrentChannel(rvAdapter.currentId - 1)
                    }
                }

                KeyEvent.KEYCODE_DPAD_LEFT -> {
                    val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
                    audioManager.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI)
                }

                KeyEvent.KEYCODE_DPAD_RIGHT -> {
                    val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
                    audioManager.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI)
                }

                KeyEvent.KEYCODE_DPAD_CENTER -> {
                    if (ll_channel_list.visibility == View.VISIBLE) {
                        rvAdapter.showChannelInfo(false, true)
                    } else {
                        rvAdapter.showChannelInfo(true, true)
                    }
                    rvAdapter.changeNextChannelSource()
                }

                KeyEvent.KEYCODE_BACK -> {

                }
            }
        }
        return true
    }

    inner class RvAdapter : Adapter<RvAdapter.ViewHolder>() {
        var playingChannelSource = 0
        var currentId = 0;
        var countDownTimer: CountDownTimer? = null

        inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            val tv_channel_name: TextView = itemView.findViewById(R.id.tv_channel_name)
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RvAdapter.ViewHolder {
            val view = LayoutInflater.from(this@MainActivity)
                .inflate(R.layout.item_channel_item, parent, false)
            return ViewHolder(view)
        }

        override fun onBindViewHolder(holder: RvAdapter.ViewHolder, position: Int) {
            holder.tv_channel_name.setText("${(position + 1)}.${channelBean[position].name}")
            if (channelBean[position] == currentPlayingChannel) {
                currentId = position
                holder.itemView.setBackgroundColor(Color.parseColor("#33ff0000"))
            } else {
                holder.itemView.setBackgroundColor(Color.parseColor("#33000000"))
            }
            holder.tv_channel_name.setOnClickListener {
                rvAdapter.setCurrentChannel(position)
            }
        }

        override fun getItemCount(): Int {
            return channelBean.size
        }

        fun showChannelInfo(isShowInfo: Boolean, showAllProgram: Boolean) {
            if (!isShowInfo) {
                ll_channel_list.visibility = View.INVISIBLE
                tv_channel_name.visibility = View.INVISIBLE
                tv_channel_playing_info.visibility = View.INVISIBLE
                tv_channel_program_next.visibility = View.INVISIBLE
                tv_all_tv_program.visibility = View.INVISIBLE
                return
            }
            ll_channel_list.visibility = View.VISIBLE
            tv_channel_name.visibility = View.VISIBLE
            tv_channel_playing_info.visibility = View.VISIBLE
            tv_channel_program_next.visibility = View.VISIBLE
            tv_all_tv_program.visibility =
                if (showAllProgram == true) View.VISIBLE else View.INVISIBLE
            countDownTimer?.cancel()
            countDownTimer = object : CountDownTimer(5000, 1000) {
                override fun onTick(millisUntilFinished: Long) {
                }

                override fun onFinish() {
                    ll_channel_list.visibility = View.INVISIBLE
                    tv_channel_name.visibility = View.INVISIBLE
                    tv_channel_playing_info.visibility = View.INVISIBLE
                    tv_channel_program_next.visibility = View.INVISIBLE
                    tv_all_tv_program.visibility = View.INVISIBLE
                }
            }
            countDownTimer?.start()
        }

        fun setCurrentChannel(currentId: Int, channelSourceId: Int = 0) {
            this.currentId = currentId
            currentPlayingChannel = channelBean[currentId]
            tv_channel_name.text = "${currentId + 1}.${currentPlayingChannel?.name}"
            tv_channel_playing_info.text = ""
            tv_channel_program_next.text = ""
            tv_all_tv_program.text = ""
            toChannelProgramInfoApi(currentPlayingChannel)
            playingChannelSource =
                if (currentPlayingChannel!!.url.size > channelSourceId) channelSourceId else 0
//            if (playingChannelSource == -1) {
//                progress_indicator.visibility = View.GONE
//                Toast.makeText(this@MainActivity, "当前频道无源", Toast.LENGTH_LONG).show()
//                countDownTimerOfPlayReady.cancel()
//                return
//            }
            var urlStr = currentPlayingChannel!!.url[playingChannelSource]
            Log.e("@@@", "channel->" + currentPlayingChannel!!.url[playingChannelSource])
            val mediaItem = MediaItem.fromUri(urlStr)
            player.setMediaItem(mediaItem)
            player.prepare()
            player.playWhenReady = true
            styled_player_view.player = player
            showChannelInfo(true, false)
            rvAdapter.notifyDataSetChanged()
            rv_channel.scrollToPosition(currentId)
            countDownTimerOfPlayReady.start()
            saveLastPlayPosition(currentId)
        }

        fun changeNextChannelSource() {
            playingChannelSource = playingChannelSource + 1
            setCurrentChannel(currentId, playingChannelSource)
        }
    }

    data class ChannelBean(var name: String, var url: MutableList<String>)

    fun toChannelProgramInfoApi(channelBean: ChannelBean?) {
        if (channelBean == null) {
            return
        }
        if (!channelBean.name.contains("cctv")) {
            return
        }
        var instance = Calendar.getInstance()
        // 将时区设置为北京时间
        instance.timeZone = TimeZone.getTimeZone("GMT+8:00");
        var year = instance.get(Calendar.YEAR)
        var month = instance.get(Calendar.MONTH) + 1
        var day = instance.get(Calendar.DAY_OF_MONTH)
        RetrofitUtils.getController(Api::class.java, this)
            .channelProgramInfoApi(
                c = channelBean.name.toLowerCase(),
                d = "${year}${if (month < 10) "0$month" else month}${if (day < 10) "0$day" else day}"
            ).enqueue(object : Callback<ResponseBody> {
                override fun onFailure(call: Call<ResponseBody>, t: Throwable) {

                }

                override fun onResponse(
                    call: Call<ResponseBody>,
                    response: retrofit2.Response<ResponseBody>
                ) {
                    try {
                        var isStartPushNextProgram = false
                        var maxShowNextCount = 2
                        var nextString: java.lang.StringBuilder = java.lang.StringBuilder()
                        var allTvProgremString: java.lang.StringBuilder = java.lang.StringBuilder()
                        val sdf = SimpleDateFormat("HH:mm")

                        var string = response.body()?.string()
                        string = string?.replace("setItem1(", "")?.replace(");", "")
                        var parseObject = JSON.parseObject(string)
                        var data = parseObject.getJSONObject("data")
                        var cctv = data.getJSONObject(channelBean.name.toLowerCase())
                        var isLive = cctv.getString("isLive")
                        var list = cctv.getJSONArray("list")
                        tv_channel_playing_info.text = "正在播出：${isLive}"
                        if (!list.isNullOrEmpty()) {
                            for (i in 0 until list.size) {
                                var listItem = list[i] as JSONObject
                                var startTime = listItem.getLong("startTime") * 1000
                                var endTime = listItem.getLong("endTime") * 1000
                                var title = listItem.getString("title")
                                if (isStartPushNextProgram && maxShowNextCount > 0) {
                                    if (maxShowNextCount == 2) {
                                        nextString.append("节目预告：\n")
                                    }
                                    nextString.append("${sdf.format(startTime)}  ${title}\n")
                                    maxShowNextCount--
                                    if (maxShowNextCount <= 0) {
                                        tv_channel_program_next.text = nextString.toString()
                                    }
                                }

                                if (instance.timeInMillis >= startTime && instance.timeInMillis <= endTime && !isStartPushNextProgram) {
                                    isStartPushNextProgram = true
                                }

                                allTvProgremString.append("${sdf.format(startTime)}  ${title}  > ")
                            }
                            tv_all_tv_program.text = allTvProgremString
                        }
                    } catch (e: Exception) {
                    }
                }
            })
    }

    fun saveLastPlayPosition(pos: Int) {
        val sp = getSharedPreferences("last_play_position", Context.MODE_PRIVATE)
        sp.edit().putInt("last_play", pos).apply()
    }

    fun getLastPlayPosition(): Int {
        val sp = getSharedPreferences("last_play_position", Context.MODE_PRIVATE)
        return sp.getInt("last_play", 0)
    }
}